-- 合服程序
-- merge 主入口 
-- handleChar 处理角色表

DB1_IP = "127.0.0.1"
DB1_NAME = "d5_qq_S199991"
DB1_USER = "d5_debug"
DB1_PASS = "d5_debug"
DB1_SVR_NAME = "仙启天元"
DB1_SVR_INDEX = 199991

DB2_IP = "127.0.0.1"
DB2_NAME = "d5_qq_S100001"
DB2_USER = "d5_debug"
DB2_PASS = "d5_debug"
DB2_SVR_NAME = "仙宗再现"
DB2_SVR_INDEX = 100001

DB3_IP = "127.0.0.1"
DB3_NAME = "d5_merge"
DB3_USER = "d5_debug"
DB3_PASS = "d5_debug"

local mongo1 = _G.lua_mongo1
local mongo2 = _G.lua_mongo2
local mongo3 = _G.lua_mongo3
local mongo4 = _G.lua_mongo4
local mongo5 = _G.lua_mongo5

db_char				=	"char"						-- 角色表
db_family     =   "family"          -- 军团
db_friend     =   "friend"          -- 好友
db_mail       =   "mail"            -- 邮件
db_market               =       "market"             -- 市场记录表
db_rank                 =       "rank"               -- 排行榜相关（不处理,下次登陆刷新)
db_server               =       "server"             -- 服务器全局相关
db_pay                  =       "pay"                -- 充值记录表
db_worldboss            =       "worldboss"          -- 世界BOSS(不处理）
db_wildboss             =       "wildboss"           -- 野外BOSS(不处理）
db_adminBroadcast       =       "adminBroadcast"     -- 广播(不处理)
db_taskPool             =       "taskPool"           -- 日常任务池(不处理)
db_dyMonster            =       "dyMonster"          -- 动态属性怪物
db_open_middle          =       "open_middle"        -- 跨服是否开启
db_dateact              =       "dateact"            -- 定时活动


local function getTableName(index, name)
	if index == 1 then
		return DB1_NAME .. "." .. name
	elseif index == 2 then
		return DB2_NAME .. "." .. name
	elseif index == 3 then
		return DB3_NAME .. "." .. name
	else
		assert(nil, "index invalid")
	end
end

-- 确认配置合法性
local function confirmConfig()
	print("merge db begin! Please ensure the db config first")
	print("DB1 IP:" .. DB1_IP .. " NAME:" .. DB1_NAME .. " SVRNAME:" .. DB1_SVR_NAME .. " SVRINDEX:" .. DB1_SVR_INDEX)
	print("DB2 IP:" .. DB2_IP .. " NAME:" .. DB2_NAME .. " SVRNAME:" .. DB2_SVR_NAME .. " SVRINDEX:" .. DB2_SVR_INDEX)
	print("DBMERGE IP:" .. DB3_IP .. " NAME:" .. DB3_NAME)
	
	local inputCnt = 0
	
	while inputCnt < 2 do
		print("are you sure to do this?(yes or cancel)")
		local ret = io.read("*line")
		if ret == "yes" then
			return true
		elseif ret == "cancel" then
			print("cancel! Press any key to exit")
			io.read("*line")
			return
		end	
		inputCnt = inputCnt + 1	
	end
	print("cancel! Press any key to exit")
	io.read("*line")
end

-- 连接数据库确认
local function checkDBConnect()
	mongo1.client(DB1_IP)
	mongo1.auth(DB1_NAME, DB1_USER, DB1_PASS)
	
	mongo2.client(DB2_IP)
	mongo2.auth(DB2_NAME, DB2_USER, DB2_PASS)
	
	mongo3.client(DB3_IP)
	mongo3.auth(DB3_NAME, DB3_USER, DB3_PASS)
	
	mongo4.client(DB1_IP)
	mongo4.auth(DB1_NAME, DB1_USER, DB1_PASS)
	
	mongo5.client(DB2_IP)
	mongo5.auth(DB2_NAME, DB2_USER, DB2_PASS)
	
	
	mongo1.index(getTableName(1, db_char), "name")
	mongo2.index(getTableName(2, db_char), "name")
	
	return true
end

-- 导出数据库数据确认
local function checkDB3Empty()
	mongo3.find(getTableName(3, db_char), {})
	local data = {}
	if mongo3.next(data) then
		print("DB3 has data please ensure its empty first! Press any key to exit")
		io.read("*line")
		return
	end
	
	return true
end

local function loadRoleByName(name, mongo, index)
	local QueryByName = {}		--按名字查询
	QueryByName.name = name
	local data = {}
	mongo.find(getTableName(index, db_char), QueryByName)
	if mongo.next(data) then
		return data
	end
end

local function loadFamilyByName(name, mongo, index)
	local QueryByName = {}		--按名字查询
	QueryByName.familyName = name
	local data = {}
	mongo.find(getTableName(index, db_family), QueryByName)
	if mongo.next(data) then
		return data
	end
end

function merge()
	if not confirmConfig() then	return end
	if not checkDBConnect() then return end
	if not checkDB3Empty() then	return end
	
	local begint = os.time()
	
	handleChar() -- 角色表
	
	handleFriend() -- 好友表
	
	handleFamily() -- 军团表
	
	handleMail() -- 邮件表
	
	handleMarket() -- 市场表
	
	handlePay() -- 充值表
	
	handleServer() --全局服务表
	
	handleRank()  -- 排行榜
	
	handleDyMonster() --动态属性怪物
	
	handleMiddleOpen() -- 跨服配置
	
	handleDateAct() -- 每日活动
	
	local endt = os.time()
	
	print(begint, endt, endt - begint)
	
	print("merge db success!Press any key to exit")
	io.read("*line")
end

local function checkCharValid(data, dbServerIndex)
	if not data then
		return 
	end
	
	-- 正常账号以区号开头
--	local i = string.find(data.account, dbServerIndex)
--	if i ~= 1 then
--		return
--	end
	
	return true	
end

local ITEM_ID_CHANGENAME = 13224					 --改名道具
local function sendItemChangeName(uuid)
	local mail = {}
	mail.mailType = 1
    mail.senderUuid = nil
    mail.receiverUuid = uuid
    mail.content = "由于合服时存在与你同名的玩家，现赠予你改名道具"
    mail.sendTime = os.time()
	mail.gridList = {[1] = {id=ITEM_ID_CHANGENAME, cnt=1, bind=true}}
	mail.title = "亲，你重名了" 
	mail.isRead = 0	
	mongo3.insert(getTableName(3, db_mail), mail)
end

local function init()

end

-- 删除日常任务
local function delTaskDaily(data)
	-- 25000 - 30000 的是日常
	if not data then
		return
	end	
	for i = data.taskRecordLen - 1, 0, -1 do
	   if data.taskRecord[i].taskid > 25000 and data.taskRecord[i].taskid < 28000 then
	       data.taskRecord[i] = data.taskRecord[data.taskRecordLen - 1]
	       data.taskRecord[data.taskRecordLen - 1] = nil
	       data.taskRecordLen = data.taskRecordLen - 1
	   end
	end
end

local newNameList = {}
local newNameList1 = {}
local newNameList2 = {}
local function getNewRoleName(data, index)
	local name = data.name
	local zone = data.svrIndex % 100000
	if data.svrIndex == 199991 then
	   zone = 0
	end
	local exName = "[" .. zone .."]"
	local isChange = false
	while true do
		local data1,data2
		local data3 = newNameList[name]
		
		if index == 1 then
			data1 = loadRoleByName(name, mongo1, 1)
			data2 = loadRoleByName(name, mongo2, 2)	
		else
			data1 = loadRoleByName(name, mongo2, 2)
			data2 = loadRoleByName(name, mongo1, 1)	
		end			
			
		-- 有相同名字的人，则等级低改名
		local isAdd
		if isChange and data1 then
			if data.lv < data1.lv or (data.lv == data1.lv and data.exp < data1.exp) then
				isAdd = true
			end
			if index == 2 and (data.lv == data1.lv and data.exp == data1.exp)  then
				isAdd = true
			end
		end
		if data2 then
			if data.lv < data2.lv or (data.lv == data2.lv and data.exp < data2.exp) then
				isAdd = true
			end		
			if index == 2 and (data.lv == data2.lv and data.exp == data2.exp)  then
				isAdd = true
			end
		end
		if data3 then
			if data.lv < data3.lv or (data.lv == data3.lv and data.exp < data3.exp) then
				isAdd = true
			end		
			if data.lv == data3.lv and data.exp == data3.exp then
				isAdd = true
			end
		end
		
		if isAdd then
			name = name .. exName
			isChange = true
		else
			break
		end
	end
	
	return name, isChange
end

local function insertCharData(data)
	if not data then
		return
	end
--	data.mergeServer = {}
--	data.mergeServerConsumePoint = nil
	mongo3.insert(getTableName(3, db_char), data)
end


local function offlinePK(data)
  if data.offlinePkRank > 0 then
      data.offlinePkRank = 0 
      data.offlinePkRewardRank = 0
  end
end
-- 角色表
local sameUuidList = {}
function handleChar() 
	print("char db merge begin")

	local char1Cnt = 0
	local char1ValidCnt = 0
	local char2Cnt = 0
	local char2ValidCnt = 0
	local char3Cnt = 0
	local sameNameCnt = 0
	local sameUuidCnt = 0
	
	local cntt = 0

	mongo4.find(getTableName(1, db_char), {})
	while true do
		cntt = cntt + 1
		if (cntt % 10000) == 0 then
			_G.collectgarbage("step", 100000)
		end

		local data = {}
		if not mongo4.next(data) then
			break
		end
		
		char1Cnt = char1Cnt + 1		
		
		if checkCharValid(data, data.svrIndex) then
			char1ValidCnt = char1ValidCnt + 1
			char3Cnt = char3Cnt + 1
			local oldName = data.name
			local newName, isChange = getNewRoleName(data, 1)
			data.name = newName
			if isChange then
--				sendItemChangeName(data._id)
				sameNameCnt = sameNameCnt + 1
				newNameList[newName] = data
				newNameList1[oldName] = newName
				--print("db1 sanme name:", data.name, " uuid:", data._id, "account", data.account, "lv", data.lv )
			end
			
			--print("db1 name:", data.name, " uuid:", data._id)
			delTaskDaily(data)
			offlinePK(data)
			
			insertCharData(data)
			
		end
	end

	_G.collectgarbage("step", 100000)
	
	mongo5.find(getTableName(2, db_char), {})
	while true do
        cntt = cntt + 1
        if (cntt % 10000) == 0 then
                _G.collectgarbage("step", 100000)
        end

		local data = {}
		if not mongo5.next(data) then
			break
		end

		char2Cnt = char2Cnt + 1

		if checkCharValid(data, data.svrIndex) then
			char2ValidCnt = char2ValidCnt + 1
			char3Cnt = char3Cnt + 1
			local oldName = data.name
			local newName, isChange = getNewRoleName(data, 2)
			data.name = newName
			if isChange then
--				sendItemChangeName(data._id)
				sameNameCnt = sameNameCnt + 1
				newNameList[newName] = data
				newNameList2[oldName] = newName
				
				--print("db2 sanme name:", data.name, " uuid:", data._id, "account", data.account, "lv", data.lv )
			end
			
			--print("db2 name:", data.name, " uuid:", data._id)
			delTaskDaily(data)
			offlinePK(data)
			
			local QueryByUuid = {}		--按名字查询
			QueryByUuid._id = data._id
			mongo3.find(getTableName(3, db_char), QueryByUuid)
			local data2 = {}
			if mongo3.next(data2) then
				-- 悲催的uuid重复了
				sameUuidCnt = sameUuidCnt + 1
				data._id = nil
				insertCharData(data)
				sameUuidList[data2._id] = data._id
				print("old uuid:", data2._id,  "new uuid:", data._id)				
			else
				insertCharData(data)
			end		
		end
	end	
	
	
	print("db1 has char:", char1Cnt, " valid:", char1ValidCnt)
	print("db2 has char:", char2Cnt, " valid:", char2ValidCnt)
	print("after merge db3 has char:", char3Cnt)
	print("char has same name count:", sameNameCnt)
	print("char has same uuid count:", sameUuidCnt)
	print("char db merge end")
end

local function replaceUuid(data, oldUuid, newUuid)
	
	if type(data) ~= "table" then
		return
	end
	
	for k, v in pairs(data) do
		if type(v) == "table" then
			replaceUuid(v, oldUuid, newUuid)
		else
			if v == oldUuid then
				data[k] = newUuid
				--print(k, oldUuid, newUuid)
			end
		end
	end
end

local function replaceName(data, oldName, newName)
  
  if type(data) ~= "table" then
    return
  end
  
  for k, v in pairs(data) do
    if type(v) == "table" then
      replaceUuid(v, oldName, newName)
    else
      if v == oldName then
        data[k] = newName
        --print(k, oldUuid, newUuid)
      end
    end
  end
end

local function copyDBTable(dbName, index, mongo, isSolveUuid)
	mongo.find(getTableName(index, dbName), {})
	while true do
		local data = {}
		if not mongo.next(data) then
			break
		end
		
		if dbName == db_mail then
			mongo3.find(getTableName(3, dbName), {})
			local tempData = {}
			if mongo3.next(tempData) then 
				data._id = nil
			end
		end
		
		-- 处理相同uuid问题
		if isSolveUuid then
			for oldUuid, newUuid in pairs(sameUuidList) do
				replaceUuid(data, oldUuid, newUuid)
			end
		end
		
		local isNoInsert 
		
		--邮件超过7天不插入
		if dbName == db_mail then
			if os.time() - data.sendTime > 7 * 86400 then
				isNoInsert = true
			end
		end
		
		if not isNoInsert then
			mongo3.insert(getTableName(3, dbName), data)
		end
	end
end

 -- 好友表
function handleFriend()
	print("friend db merge begin")
	copyDBTable(db_friend, 1, mongo1)
	copyDBTable(db_friend, 2, mongo2, true)	
	print("friend db merge end")
end 

local newFamilyNameList = {}
local function getNewFamilyName(data, index, dbServerIndex)
	local name = data.familyName
	local zone = dbServerIndex % 100000
	if dbServerIndex == 199991 then
	   zone = 0
	end
	local exName = "[" ..zone.."]"
	local isChange = false

	while true do
		local data1,data2
		local data3 = newFamilyNameList[name]
		
		if index == 1 then
			data1 = loadFamilyByName(name, mongo1, 1)
			data2 = loadFamilyByName(name, mongo2, 2)	
		else
			data1 = loadFamilyByName(name, mongo2, 2)
			data2 = loadFamilyByName(name, mongo1, 1)	
		end					
			
		data.familyExp = data.familyExp or 0
		-- 有相同名字的家族，则等级低改名
		local isAdd
		if isChange and data1 then
			data1.familyExp = data1.familyExp or 0
			if data.familyLv < data1.familyLv or (data.familyLv == data1.familyLv and data.familyExp < data1.familyExp) then
				isAdd = true
			end
			if index == 2 and (data.familyLv == data1.familyLv and data.familyExp == data1.familyExp)  then
				isAdd = true
			end
		end
		if data2 then
			data2.familyExp = data2.familyExp or 0
			if data.familyLv < data2.familyLv or (data.familyLv == data2.familyLv and data.familyExp < data2.familyExp) then
				isAdd = true
			end		
			if index == 2 and (data.familyLv == data2.familyLv and data.familyExp == data2.familyExp)  then
				isAdd = true
			end
		end
		if data3 then
			data3.familyExp = data3.familyExp or 0
			if data.familyLv < data3.familyLv or (data.familyLv == data3.familyLv and data.familyExp < data3.familyExp) then
				isAdd = true
			end		
			if data.familyLv == data3.familyLv and data.familyExp == data3.familyExp then
				isAdd = true
			end
		end
		
		if isAdd then
			name = name .. exName
			isChange = true
		else
			break
		end
	end
	
	return name, isChange
end


-- 家族表
function handleFamily()
	print("family db family begin")
	
	local family1Cnt = 0
	local family2Cnt = 0
	local family3Cnt = 0
	local sameNameCnt = 0
	
	mongo4.find(getTableName(1, db_family), {})
	while true do
		local data = {}
		if not mongo4.next(data) then
			break
		end
		
		family1Cnt = family1Cnt + 1
		family3Cnt = family3Cnt + 1
		
		local newName, isChange = getNewFamilyName(data, 1, DB1_SVR_INDEX)
		data.familyName = newName
		if isChange then
			sameNameCnt = sameNameCnt + 1
			newFamilyNameList[newName] = data
		end
		mongo3.insert(getTableName(3, db_family), data)
	end
	
	mongo5.find(getTableName(2, db_family), {})
	while true do
		local data = {}
		if not mongo5.next(data) then
			break
		end

		family2Cnt = family2Cnt + 1
		family3Cnt = family3Cnt + 1
		
		local newName, isChange = getNewFamilyName(data, 2, DB2_SVR_INDEX)
		data.familyName = newName
		if isChange then
			sameNameCnt = sameNameCnt + 1
			newFamilyNameList[newName] = data
		end	
		
		for oldUuid, newUuid in pairs(sameUuidList) do
			replaceUuid(data, oldUuid, newUuid)
		end
		mongo3.insert(getTableName(3, db_family), data)
	end	
	
	
	print("db1 has family:", family1Cnt)
	print("db2 has family:", family2Cnt)
	print("after merge db3 has family:", family3Cnt)	
	print("family has same name count:", sameNameCnt)
	print("family db family end")
end

-- 市场表
function handleMarket()
	print("market db merge begin")
	copyDBTable(db_market, 1, mongo1)
	copyDBTable(db_market, 2, mongo2, true)
	print("market db merge end")
end
	
-- 邮件表
function handleMail()
	print("mail db merge begin")
	copyDBTable(db_mail, 1, mongo1)
	copyDBTable(db_mail, 2, mongo2, true)
	print("mail db merge end")
end

--服务器全局数据
function handleServer()
  print("server db  merge begin")
  local server = {}
  mongo1.find(getTableName(1,db_server), {serverCommon_Id = "serverCommon"})
  local server1 
  if mongo1.next(server) then
        server1 = server
  end
  local server2
  mongo2.find(getTableName(2,db_server), {serverCommon_Id = "serverCommon"})
  server ={}
  if mongo2.next(server) then
        server2 = server
  end
  server = nil
  if not server1 then
      server = server2
  elseif not server2 then
      server = server1
  elseif server1.ServerOpenTime < server2.ServerOpenTime then
      server = server1
  else
      server = server2
  end
  if server then
      server._id = nil
      server.ServerOfflinePkTotalRank = nil
      server.ComplexSrvTime = os.time()
      mongo3.insert(getTableName(3, db_server), server)
  end
  print("server db  merge end")  
end
-- 充值表
function handlePay()
  print("pay db merge begin")
  copyDBTable(db_pay, 1, mongo1)
  copyDBTable(db_pay, 2, mongo2, true)
  print("pay db merge end")
end


LV_RANK_TYPE = 1 --等级榜
POWER_RANK_TYPE = 2 --战力榜
SB_RANK_TYPE = 3 --神兵榜
HORSE_RANK_TYPE = 4 --铁骑榜
PET_RANK_TYPE = 5 --神将榜
PATA_RANK_TYPE = 6 --过关斩将榜
BAOWU_RANK_TYPE = 7 --宝物榜

RANK_MAX_CNT = 50 --排行榜最大个数
local function getRankData(tb, mongo, index, type)
  local dbType = {type = type}
  mongo.find(getTableName(index,db_rank), dbType)
  while true do
     local data = {}
     if not mongo.next(data) then
        break
     end
     tb[#tb + 1] = data
     
     data.mergeTmpIndex = index
  end
  return tb
end
local function insertRankData(tb, rankIndex)
  for i = 1, RANK_MAX_CNT do
      if tb[i] then
        tb[i][rankIndex] = i
        if tb[i].mergeTmpIndex == 2 then
           for oldUuid, newUuid in pairs(sameUuidList) do
              replaceUuid(tb[i], oldUuid, newUuid)
           end
           for oldName,newName in pairs(newNameList2) do
              replaceName(tb[i], oldName, newName)
           end
        else
           for oldName,newName in pairs(newNameList1) do
              replaceName(tb[i], oldName, newName)
           end
        end
        tb[i].mergeTmpIndex = nil
        tb[i]._id = nil
        mongo3.insert(getTableName(3,db_rank), tb[i])
      end
  end
end
function sortFunc_lv(a, b)
  if a.lv == b.lv then
    return a.create < b.create
  end
  return a.lv > b.lv
end
function sortFunc_power(a, b)
  if a.power == b.power then
    return a.create < b.create
  end
  return a.power > b.power
end

function sortFunc_sbPower(a, b)
  if a.sbPower == b.sbPower then
    return a.create < b.create
  end
  return a.sbPower > b.sbPower
end
function sortFunc_horsePower(a, b)
  if a.horsePower == b.horsePower then
    return a.create < b.create
  end
  return a.horsePower > b.horsePower
end

function sortFunc_petPower(a, b)
  if a.petPower == b.petPower then
    return a.create < b.create
  end
  return a.petPower > b.petPower
end
function sortFunc_pata_max(a, b)
  if a.pata_max == b.pata_max then
    return a.create < b.create
  end
  return a.pata_max > b.pata_max
end
function sortFunc_baowu_max(a, b)
  if a.baowuPower == b.baowuPower then
    return a.create < b.create    
  end
  return a.baowuPower > b.baowuPower
end


-- 排行榜
function handleRank()
  print("rank db merge begin")
  _G.collectgarbage("step", 100000)
  local lvRank = {}
  getRankData(lvRank, mongo1, 1, LV_RANK_TYPE)
  getRankData(lvRank, mongo2, 2, LV_RANK_TYPE)
  table.sort(lvRank, sortFunc_lv)
  insertRankData(lvRank, "index")
  
  local powerRank = {}
  getRankData(powerRank, mongo1, 1, POWER_RANK_TYPE)
  getRankData(powerRank, mongo2, 2, POWER_RANK_TYPE)
  table.sort(powerRank, sortFunc_power)
  insertRankData(powerRank, "index")
  
  
  local sbRank = {}
  getRankData(sbRank, mongo1, 1, SB_RANK_TYPE)
  getRankData(sbRank, mongo2, 2, SB_RANK_TYPE)
  table.sort(sbRank, sortFunc_sbPower)
  insertRankData(sbRank, "index")
  
  _G.collectgarbage("step", 100000)
  local horseRank = {}
  getRankData(horseRank, mongo1, 1, HORSE_RANK_TYPE)
  getRankData(horseRank, mongo2, 2, HORSE_RANK_TYPE)
  table.sort(horseRank, sortFunc_horsePower)
  insertRankData(horseRank, "index")
  
  local petRank = {}
  getRankData(petRank, mongo1, 1, PET_RANK_TYPE)
  getRankData(petRank, mongo2, 2, PET_RANK_TYPE)
  table.sort(petRank, sortFunc_petPower)
  insertRankData(petRank, "index")  
  
  local pataRank = {}
  getRankData(pataRank, mongo1, 1, PATA_RANK_TYPE)
  getRankData(pataRank, mongo2, 2, PATA_RANK_TYPE)
  table.sort(pataRank, sortFunc_pata_max)
  insertRankData(pataRank, "index")
  
  local baowuRank = {}
  getRankData(baowuRank, mongo1, 1, BAOWU_RANK_TYPE)
  getRankData(baowuRank, mongo2, 2, BAOWU_RANK_TYPE)
  table.sort(baowuRank, sortFunc_baowu_max)
  insertRankData(baowuRank, "index")  
  
  _G.collectgarbage("step", 100000)
  print("rank db merge end")
end

local function getDyMonsterDB(mongo, index)
  mongo.find(getTableName(index,db_dyMonster))
  local db = {}
  while true do
        local nReader = {}
        if not mongo.next(nReader) then
            break
        end
        db[nReader.monsterID] = nReader 
  end
  return db
end
function handleDyMonster()
  print("monster db merge begin")
  _G.collectgarbage("step", 100000)
  local db1 = getDyMonsterDB(mongo1, 1)
  local db2 = getDyMonsterDB(mongo2, 2)
  for k,v in pairs(db2) do
      if db1[k] == nil then
          db1[k] = v
      elseif db1[k].lv < v.lv then
          db1[k] = v
      end
  end
  for k, v in pairs(db1) do
      v._id = nil
      mongo3.insert(getTableName(3,db_dyMonster), v)
  end
  print("monster db merge end")
  _G.collectgarbage("step", 100000)
end

function handleMiddleOpen()
  print("middleOpen db merge begin")
  
  copyDBTable(db_open_middle, 1, mongo1)
  
  print("middleOpen db merge end")  
end

local function getDateActData(mongo, index)
  mongo.find(getTableName(index,db_dateact))
  local db = {}
  while true do
        local nReader = {}
        if not mongo.next(nReader) then
            break
        end
        local actConfigID = nReader.actConfigID
        if actConfigID then
          db[actConfigID] = nReader
        end 
  end
  return db
end

function handleDateAct()
  _G.collectgarbage("step", 100000)
  local db1 = getDateActData(mongo1, 1)
  local db2 = getDateActData(mongo2, 2)
  for k,v in pairs(db2) do
      if v._data and db1[k] then
          for kk,vv in pairs(v._data) do
              if not db1[k]._data[kk] then
                  db1[k]._data[kk] = vv
              end
          end
      end
  end
  for k, v in pairs(db1) do
      v._id = nil
      mongo3.insert(getTableName(3,db_dateact), v)
  end
  print("monster db merge end")
  _G.collectgarbage("step", 100000)  
end
init()
merge()